import { Injectable } from '@nestjs/common';
import { User } from '../../entities/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ApiErrorCode } from '../../common/enums/api-error-code.enum';
import {
  Response,
  ResponseParam,
  CurrentError,
  UserError,
} from '../../common/enums/response';
import { WxApi } from '../../common/wxapi/wxapi.service';
import { Utils } from '../../util/utils.service';
import { AdminRole, UserRole } from 'src/entities/user.entity';
import { Auth } from '../../auth/auth';
import { CreateToAdminDto, PgaeDto } from './user.dto';

@Injectable()
export class UserService {
  constructor(
    private readonly wxApi: WxApi,
    private readonly utils: Utils,
  ) {}
  @InjectRepository(User) private readonly clientUser: Repository<User>;

  /**
   * @description: save用户
   * @param {json} param 传入的数据库值
   * @return:
   */
  public async created(openid: string): Promise<number> {
    let clientUser: User = await this.clientUser.findOneBy({ openid: openid });
    //如果存在该用户，更新内容
    try {
      if (clientUser && clientUser.phone) {
        return 1;
      }
      if (!clientUser) {
        await this.clientUser.save({
          openid,
          role: AdminRole.General,
          userRole: UserRole.General,
        });
      }
      return 2;
    } catch (error) {
      return 3;
    }
  }
  /**
   * @description: 更新用户openid
   * @param {json} param 传入的数据库值
   * @return:
   */
  public async pudOpenid(id: number, openid: string): Promise<number> {
    try {
      await this.clientUser.update({ id }, { openid: openid });
      return 1;
    } catch (error) {
      return 2;
    }
  }

  /**
   * @description: 后台创建用户信息
   * @param {string} openid
   * @return:
   */
  public async createToAdmin(param: CreateToAdminDto) {
    try {
      const userInfo: User = await this.clientUser.findOneBy({
        phone: param.phone,
      });
      if (userInfo) {
        return UserError.USER_PHONE_ERROR;
      }
      await this.clientUser.save(param);
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_SET_SUCCESS,
        data: null,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_SET_FAIL;
    }
  }

  /**
   * @description: 后台修改用户信息
   * @param {string} openid
   * @return:
   */
  public async putToAdmin(id: number, param: CreateToAdminDto) {
    try {
      await this.clientUser.update({ id }, param);
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_UPDATE_SUCCESS,
        data: null,
      };
      return Response(responseParam);
    } catch (error) {
      console.log(error);
      return CurrentError.LACK_UPDATE_FAIL;
    }
  }

  /**
   * @description: 手机号授权登录
   * @param {string} openid
   * @return:
   */
  public async loginByPhone(openid: string, code: string) {
    try {
      const access_token: string = await this.wxApi.getclientUserAccessToken();
      const res: any = await this.wxApi.getUserphonenumber(code, access_token);
      // 写入用户数据
      const userInfo: User = await this.clientUser.findOneBy({ openid });
      await this.clientUser.update(
        { openid },
        { phone: res.phone_info.phoneNumber },
      );
      const auth = new Auth();
      const token: string = await auth.createToken(openid, userInfo.role);
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_GET_SUCCESS,
        data: token,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_GET_FAIL;
    }
  }

  /**
   * @description: 获取用户id
   * @param {string} openid
   * @return:
   */
  public async getUserInfo(id: number) {
    const clientUser: User = await this.clientUser.findOneBy({ id });
    let responseParam: ResponseParam = {
      message: ApiErrorCode.LACK_GET_SUCCESS,
      data: clientUser,
    };
    return Response(responseParam);
  }

  /**
   * @description: 获取用户id
   * @param {string} openid
   * @return:
   */
  public async clientUserIdbyOpenid(openid: string): Promise<number> {
    const clientUser: User = await this.clientUser.findOneBy({ openid });
    return clientUser.id;
  }

  /**
   * @description: 获取用户id
   * @param {string} userName
   * @return:
   */
  public async clientUserIdbyUserName(userName: string): Promise<number> {
    const clientUser: User = await this.clientUser.findOneBy({
      name: userName,
    });
    return clientUser.id;
  }

  /**
   * @description: 获取用户信息
   * @param {string} openid
   * @return:
   */
  public async clientUserbyOpenidMpl(openid: string): Promise<any> {
    const clientUser: User = await this.clientUser.findOneBy({ openid });
    return clientUser;
  }

  /**
   * @description: 获取用户信息
   * @param {string} openid
   * @return:
   */
  public async clientUserbyOpenid(openid: string) {
    const clientUser: User = await this.clientUser.findOneBy({ openid });
    let responseParam: ResponseParam = {
      message: ApiErrorCode.LACK_GET_SUCCESS,
      data: clientUser,
    };
    return Response(responseParam);
  }

  /**
   * @description: 查询clientUser列表
   * @param {object} query
   * @return:
   */
  public async getClientUserList(query) {
    try {
      let data: User[] = await this.clientUser
        .createQueryBuilder('clientUser')
        .where('1')
        .skip((query.page - 1) * query.pageSize)
        .take(query.pageSize)
        .getMany();
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_GET_SUCCESS,
        data,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_GET_FAIL;
    }
  }

  /**
   * @description: 查询clientUser总数
   * @param {object} query
   *
   * @return:
   */
  public async getClientUserTotal(query): Promise<object> {
    try {
      const total: any = await this.clientUser
        .createQueryBuilder('clientUser')
        .where('1')
        .getCount();
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_GET_SUCCESS,
        data: total,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_GET_FAIL;
    }
  }

  /**
   * @description: 写入用户信息
   * @param {string} openid
   * @param {string} userAvatarUrl 头像
   * @param {string} userName 昵称
   */
  public async setClientUserInfo(
    openid: string,
    userAvatarUrl: string,
    userName: string,
  ) {
    try {
      const clientUserInfo = await this.clientUser.findOneBy({ openid });
      clientUserInfo.avatar = userAvatarUrl;
      clientUserInfo.name = userName;
      await this.clientUser.save(clientUserInfo);
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_SET_SUCCESS,
        data: null,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_SET_FAIL;
    }
  }

  /**
   * @description: 获取是否为新用户
   * @param {string} openid
   */
  public async whetherNewUser(openid: string) {
    const whetherNewUser = await this.clientUser.findOneBy({ openid });
    let responseParam: ResponseParam = {
      message: ApiErrorCode.LACK_GET_SUCCESS,
      data: whetherNewUser,
    };
    return Response(responseParam);
  }

  /**
   * @description: 获取过去七天新增用户
   * @param {type}
   */
  public async getClientUserNumWeek(): Promise<number> {
    const clientUserNum: number = await this.clientUser
      .createQueryBuilder()
      .where("YEARWEEK(date_format(creatTime,'%Y-%m-%d'),1) = YEARWEEK(now())")
      .getCount();
    return clientUserNum;
  }

  /**
   * @description: 获取用户总数
   * @param {type}
   */
  public async getClientUserNumTotal(): Promise<number> {
    const clientUserNum: number = await this.clientUser
      .createQueryBuilder()
      .getCount();
    return clientUserNum;
  }

  /**
   * 获取用户列表
   *
   * @param {number} page
   * @param {number} pageSize
   */
  public async getUserList(param: PgaeDto) {
    let userRep: any = this.clientUser.createQueryBuilder().where('1');
    if (param.name) {
      userRep.andWhere('name like :name', { name: `%${param.name}%` });
    }
    const userList: any = await userRep
      .orderBy('creatTime', 'DESC')
      .skip((param.page - 1) * param.pageSize)
      .take(param.pageSize)
      .getManyAndCount();
    let responseParam: ResponseParam = {
      message: ApiErrorCode.LACK_GET_SUCCESS,
      data: userList[0],
      count: userList[1],
    };
    return Response(responseParam);
  }

  /**
   * @description: 用户修改密码
   * @return:
   */
  public async putPassword(id: number, password: string) {
    try {
      await this.clientUser.update({ id }, { password });
      let responseParam: ResponseParam = {
        message: ApiErrorCode.LACK_UPDATE_SUCCESS,
        data: null,
      };
      return Response(responseParam);
    } catch (error) {
      return CurrentError.LACK_UPDATE_FAIL;
    }
  }
}
